package me.zhengjie.modules.fileupload.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.fileupload.domain.ElectronicMaterialFileDetailVO;
import me.zhengjie.modules.fileupload.domain.ElectronicMaterialFileVO;
import me.zhengjie.modules.fileupload.mapper.ElectronicMaterialMapper;
import me.zhengjie.modules.fileupload.service.ElectronicMaterialService;
import me.zhengjie.modules.fileupload.utils.FileUtils;
import me.zhengjie.modules.logs.domain.BusinessLog;
import me.zhengjie.modules.logs.service.BusinessLogService;
import me.zhengjie.modules.sequence.domain.Sequence;
import me.zhengjie.modules.sequence.service.SequenceService;
import me.zhengjie.tool.DateUtil;
import me.zhengjie.tool.ValidateUtil;
import me.zhengjie.utils.PageResult;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.StringUtils;
import me.zhengjie.vo.Constant;
import me.zhengjie.vo.YHConstants;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@Service
@Slf4j
@Transactional
public class ElectronicMaterialServiceImpl implements ElectronicMaterialService {

    @Resource
    private ElectronicMaterialMapper electronicMaterialMapper;
    @Resource
    BusinessLogService businessLogService;
    @Resource
    SequenceService sequenceService;

    @Override
    public PageResult<ElectronicMaterialFileDetailVO> queryList(Map param, Page<Object> page) throws IOException {
        if (ValidateUtil.isEmpty(param.get("queryType"))) {
            param.put("queryType", Constant.SFBZ_0_F);
        }
        List<String> fileTypes = new ArrayList<>();
        fileTypes.add("jpg");
        fileTypes.add("jpeg");
        fileTypes.add("png");
        fileTypes.add("gif");
        fileTypes.add("bmp");
        String queryType = param.get("queryType").toString();
        if (Constant.SFBZ_0_F.equals(queryType)) { // 查询汇总
            return PageUtil.toPage(electronicMaterialMapper.getFileList_hz(param, page));
        } else { // 查询明细
            IPage<ElectronicMaterialFileDetailVO> pageList = electronicMaterialMapper.getFileList(param, page);
            List<ElectronicMaterialFileDetailVO> list = pageList.getRecords();
            if (!ValidateUtil.isEmpty(list)) {
                for (ElectronicMaterialFileDetailVO item : list) {
                    String filename = item.getFilename();
                    String aae036 = item.getAae036().substring(0, 10);
                    Path filePath = Paths.get(Constant.UPLOAD_DIR + "/" + aae036 + "/").resolve(filename);
                    byte[] fileContent = Files.readAllBytes(filePath);
                    String base64 = Base64.getEncoder().encodeToString(fileContent);
                    String mimeType = Files.probeContentType(filePath);
                    String base64Str = "data:" + mimeType + ";base64," + base64;
                    item.setBase64(base64Str);
                    if (fileTypes.contains(item.getFiletype())) {
                        item.setFiletype("image");
                    }
                }
            }
            pageList.setRecords(list);

            return PageUtil.toPage(list);
        }
    }

    @Override
    public void deleteFile(String id) throws IOException {
        // 日志
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        ElectronicMaterialFileVO electronicMaterialFileVO = electronicMaterialMapper.selectFileById(id);
        param.put("aaz002", sequenceService.nextSequence(new Sequence("aaz002")));
        param.put("aaa121", YHConstants.AAA121_CLSC);
        param.put("aac001", electronicMaterialFileVO.getAac001());
        param.put("aae016", Constant.AAE016_1_SHTG);
        param.put("aae140", Constant.AAE140_120_JGSYDWGZRYJBYLBX);
        BusinessLog businessLog = BusinessLog.singleLog(param);
        businessLogService.save(businessLog);

        electronicMaterialMapper.updateFileStatusHz(id, "0");
    }

    @Override
    public ElectronicMaterialFileVO uploadFile(String aac001, String aaa121, String name, String id,
                                               MultipartFile file) throws IOException {
        // 参数校验
        if (StringUtils.isBlank(aac001)) {
            throw new IllegalArgumentException("人员编号不能为空");
        }
        if (StringUtils.isBlank(aaa121)) {
            throw new IllegalArgumentException("业务类型不能为空");
        }
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("上传文件不能为空");
        }

        // 文件校验
        validateFile(file);

        // 1. 处理电子材料记录(主表)
        Map query = new HashMap();
        query.put("aac001", aac001);
        query.put("aaa121", aaa121);
        query.put("id", id);
//        List<ElectronicMaterialFileVO> materialList = electronicMaterialMapper.getFileList(aac001,aaa121,id);
        List<ElectronicMaterialFileVO> materialList = electronicMaterialMapper.selectByMap(query);
        ElectronicMaterialFileVO material = new ElectronicMaterialFileVO();
        if (ValidateUtil.isEmpty(materialList)) {
            material.setId(id);
            material.setAac001(aac001);
            material.setAaa121(aaa121);
            material.setName(name);
            material.setAae100(Constant.AAE100_1_YX);
            material.setAae036(DateUtil.getStringCurDateTime());
            try {
                electronicMaterialMapper.insert(material);
                // 日志
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Object> param = new HashMap<>();
                param.put("aaz002", sequenceService.nextSequence(new Sequence("aaz002")));
                param.put("aaa121", YHConstants.AAA121_CLXZ);
                param.put("aac001", aac001);
                param.put("aab001", aaa121);
                param.put("aae016", Constant.AAE016_1_SHTG);
                param.put("aae140", Constant.AAE140_120_JGSYDWGZRYJBYLBX);
                BusinessLog businessLog = BusinessLog.singleLog(param);
                businessLogService.save(businessLog);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        } else {
            material = materialList.get(0);
        }

        // 2. 存储文件(本地)
        String fileId = UUID.randomUUID().toString();
        String fileName = fileId + "_" + file.getOriginalFilename();
        String fileType = FileUtils.getFileExtension(fileName);
        long fileSize = file.getSize();
        // 创建目标路径
        Path uploadPath = Paths.get(Constant.UPLOAD_DIR + "/" + DateUtil.getCurrentTime("yyyy-MM-dd"));
        Path filePath = uploadPath.resolve(fileName);
        // 确保目录存在
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }
        // 保存文件
        Files.copy(file.getInputStream(), filePath);

        // 3. 保存文件记录
        ElectronicMaterialFileDetailVO materialFile = new ElectronicMaterialFileDetailVO();
        materialFile.setId(fileId);
        materialFile.setMaterialid(material.getId());
        materialFile.setFilename(fileName);
        materialFile.setFiletype(fileType);
        materialFile.setFilesize(String.valueOf(fileSize));
        materialFile.setFilepath(filePath.toString());
        materialFile.setAae036(DateUtil.getStringCurDateTime());
        materialFile.setAae100(Constant.AAE100_1_YX);
        electronicMaterialMapper.insertFile(materialFile);

        // 4. 返回文件信息
        ElectronicMaterialFileVO vo = new ElectronicMaterialFileVO();

        return vo;
    }
    /**
     * 验证上传文件
     */
    private void validateFile(MultipartFile file) {
        // 文件大小限制 (10MB)
        long maxSize = 10 * 1024 * 1024;
        if (file.getSize() > maxSize) {
            throw new IllegalArgumentException("文件大小不能超过10MB");
        }

        // 文件类型检查
        String fileName = file.getOriginalFilename();
        String fileType = FileUtils.getFileExtension(fileName).toLowerCase();
//        Set<String> allowedTypes = new HashSet<>(Arrays.asList(
//                "jpg", "jpeg", "png", "pdf", "doc", "docx", "xls", "xlsx"));
        Set<String> allowedTypes = new HashSet<>(Arrays.asList(
                "jpg", "jpeg", "png", "pdf", "doc", "docx"));

        if (!allowedTypes.contains(fileType)) {
            throw new IllegalArgumentException("不支持的文件类型: " + fileType);
        }
    }

    /**
     * 格式化文件大小
     */
    private String formatFileSize(long size) {
        if (size < 1024) {
            return size + "B";
        } else if (size < 1024 * 1024) {
            return (size / 1024) + "KB";
        } else {
            return String.format("%.1fMB", size / (1024.0 * 1024.0));
        }
    }

    /**
     * 判断文件是否可预览
     */
    private boolean isPreviewable(String fileType) {
        return Arrays.asList("jpg", "jpeg", "png", "pdf").contains(fileType.toLowerCase());
    }

    /**
     * 编码文件名，解决中文乱码问题
     */
    private String encodeFileName(String fileName) {
        try {
            return URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            return fileName;
        }
    }
}
